﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using LevenBlog.Core.Data;
using LevenBlog.Core.Utils;

namespace LevenBlog.Data.SqlServer
{
    public sealed class SqlProvider : IDbProvider
    {
        private string connectionString = null;
        private uint queryNum = 0;
        private IDbConnection connection = null;
        private IDbCommand command = null;
        private IDbDataAdapter dataAdapeter = null;
        private IDbTransaction transaction = null;

        public SqlProvider()
        {
        }

        public string ConnectionString
        {
            get
            {
                if (connectionString == null)
                {
                    connectionString = WebConfig.BlogDbSetting;
                }
                return connectionString;
            }
        }

        public uint QueryNum
        {
            get
            {
                return queryNum;
            }
        }

        public IDbConnection Connection
        {
            get
            {
                if (connection == null)
                {
                    connection = new SqlConnection(ConnectionString);
                }
                return connection;
            }
        }

        public IDbCommand Command
        {
            get
            {
                if (command == null)
                {
                    command = new SqlCommand();
                    command.Connection = connection;
                }
                return command;
            }
        }

        public IDbDataAdapter DataAdapter
        {
            get
            {
                if (dataAdapeter == null)
                {
                    dataAdapeter = new SqlDataAdapter(Command as SqlCommand);
                }
                return dataAdapeter;
            }
        }

        public void AddQuery()
        {
            queryNum++;
        }

        public void Open()
        {
            Connection.Open();
        }

        public void Close()
        {
            if(connection!=null)
                Connection.Close();
        }

        public void Dispose()
        {
            Close();
            if (command != null)
                command.Dispose();
            if (connection != null)
                connection.Dispose();
            connectionString = null;
            connection = null;
            command = null;
            dataAdapeter = null;
            transaction = null;
        }

        #region 事务控制

        public bool IsInTracsaction {
            get {
                return transaction != null;
            }
        }

        public void BeginTransaction()
        {
            transaction = Connection.BeginTransaction();
            Command.Transaction = transaction;
        }

        public void BeginTransaction(IsolationLevel level)
        {
            transaction = Connection.BeginTransaction(level);
            Command.Transaction = transaction;
        }

        public void Commit()
        {
            if (transaction == null)
                throw new Exception("No transaction can Commit.");
            transaction.Commit();
            transaction.Dispose();
            transaction = null;
            command.Transaction = null;
        }

        public void Rollback()
        {
            if (transaction == null)
                throw new Exception("No transaction can Rollback.");
            transaction.Rollback();
            transaction.Dispose();
            transaction = null;
            command.Transaction = null;
        }

        #endregion

        #region Instance

        public IDbProvider CreateInstance()
        {
            return new SqlProvider();
        }

        #endregion
    }
}
